﻿using Shop.Collect;
using Shop.Model.Attr;
using Shop.Model.DB;
using Shop.RemoteModel.Goods.Model;
using Shop.Service.Helper;
using Shop.Service.Interface;
using WeDonekRpc.Client;
using WeDonekRpc.Helper;

namespace Shop.Service.lmpl
{
    internal class GoodsDetailedService : IGoodsDetailedService
    {
        private readonly IGoodsCollect _Goods;
        private readonly IGoodsAttrCollect _GoodsAttr;
        private readonly ICategoryCollect _Category;
        private readonly IFrontCategoryBindCollect _FrontBind;
        private readonly IFrontCategoryCollect _FontCategory;
        private readonly IGoodsSkuCollect _GoodsSku;
        private readonly ILogisticsTemplateCollect _Logistics;
        private readonly IGoodsSkuStateCollect _SkuState;
        private readonly ISpecGroupCollect _SpecGroup;

        public GoodsDetailedService ( IGoodsCollect goods,
            IGoodsAttrCollect goodsAttr,
            ICategoryCollect category,
            IGoodsSkuCollect goodsSku,
            ILogisticsTemplateCollect logistics,
            IGoodsSkuStateCollect skuState,
            IFrontCategoryBindCollect frontBind,
            IFrontCategoryCollect front,
            ISpecGroupCollect specGroup )
        {
            this._FontCategory = front;
            this._FrontBind = frontBind;
            this._SkuState = skuState;
            this._Logistics = logistics;
            this._Goods = goods;
            this._GoodsAttr = goodsAttr;
            this._Category = category;
            this._GoodsSku = goodsSku;
            this._SpecGroup = specGroup;
        }

        public GoodsDetailed Get ( long id )
        {
            DBGoods goods = this._Goods.Get(id);
            GoodsDetailed detailed = goods.ConvertMap<DBGoods, GoodsDetailed>();
            long[] ids = new long[]
            {
                goods.MainCategoryId,
                goods.TwoCategoryId,
                goods.ThreeCategoryId,
                goods.CategoryId
            }.Where(a => a != 0).Distinct().ToArray();
            long frontId = this._FrontBind.GetFrontCategoryId(ids);
            if ( frontId != 0 )
            {
                detailed.FrontCategory = this._FontCategory.GetFullName(frontId);
            }
            detailed.CategoryName = this._Category.GetNameList(ids);
            if ( detailed.LogisticsId.HasValue )
            {
                detailed.LogisticsName = this._Logistics.Get(detailed.LogisticsId.Value, a => a.TemplateName);
            }
            DBGoodsSku[] skus = this._GoodsSku.GetsByGoodsId(id);
            Dictionary<string, bool> state = this._SkuState.GetsSkuState(id);
            detailed.SpecGroup = this._SpecGroup.Gets(detailed.Id);
            detailed.SpecState = detailed.SpecGroup.GetSpecState(state);
            if ( !skus.IsNull() )
            {
                GoodsAttrDto[] attrs = this._GoodsAttr.Gets(id);
                detailed.Sku = skus.ToDictionary(a => a.SpecsKey, a =>
                {
                    GoodsSkuDetailed sku = a.ConvertMap<DBGoodsSku, GoodsSkuDetailed>();
                    GoodsAttrDto[] dtos = attrs.FindAll(c => c.SkuId == a.SkuId);
                    sku.Attrs = dtos.ToTree();
                    return sku;
                });
            }
            return detailed;
        }
    }
}
